package com.cm.biz;

import com.cm.biz.db.Db;
import com.cm.etax.tianjin.Tianjin;
import com.cm.kits.EnvironmentToolkit;
import com.cm.kits.HashKits;
import com.cm.rpa.config.RpaConfig;
import lombok.extern.slf4j.Slf4j;

import com.cm.etax.monitor.Monitor;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * RPA 任务处理器
 *
 * @author LWang 2023.02.03
 * @since 1.0.0
 */
@Slf4j
public final class YzhTaskExecutor {

    private final Db db;

    private final Tianjin tianjin;

    private final Monitor monitor;

    private final String instanceID;

    private final String ip;

    public YzhTaskExecutor() {

        instanceID = "%s_java_rpa".formatted(HashKits.sha256(EnvironmentToolkit.getMac().getBytes(StandardCharsets.UTF_8)));
        ip = EnvironmentToolkit.getLocalIp();
        db = new Db();
        tianjin = new Tianjin(RpaConfig.build("rpa.yaml"));
        monitor = new Monitor();

        // 心跳
        var executorService = new ScheduledThreadPoolExecutor(1, new RpaThreadFactory("RPA", true));
        var schedule = executorService.scheduleWithFixedDelay(this::doHeartbeat, 1, 3, TimeUnit.SECONDS);
        // 任务处理
        while (monitor.doNext()) {
            // 读取任务，并执行任务锁处理
            System.out.println("TODO 执行任务！");
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException ignored) {
            }
        }
        log.error("停止服务！");
        tianjin.shutdown();
        log.error("停止心跳定时任务！");
        schedule.cancel(true);
        executorService.shutdownNow();
        log.error("销毁监控服务！");
        monitor.exit();
        System.exit(0);
    }

    private void doHeartbeat() {
        try {
            log.debug("实例 {} 心跳", instanceID);
            if (!db.execute(conn -> {
                try (
                        var query = conn.prepareStatement("select `id` from `runtime_service_instances` where `id` = ?");
                        var update = conn.prepareStatement("update `runtime_service_instances` set `heartbeat_time` = now() where `id` = ?");
                        var insert = conn.prepareStatement("insert into `runtime_service_instances` (`id`, `ip`, `heartbeat_time`) values(?, ?, now())")
                ) {
                    var isUpdate = false;
                    // 查询心跳实例记录是否存在
                    query.setString(1, instanceID);
                    try (var rs = query.executeQuery()) {
                        isUpdate = rs.next();
                    }
                    if (isUpdate) {
                        // 如果心跳实例记录存在，则更新心跳记录
                        update.setString(1, instanceID);
                        update.execute();
                    } else {
                        // 如果心跳实例记录不存在，则新增心跳记录
                        insert.setString(1, instanceID);
                        insert.setString(2, ip);
                        insert.execute();
                    }
                    return true;
                }
            })) {
                log.warn("进行心跳记录失败！");
            }
        } catch (Exception e) {
            log.error("实例 {} 心跳异常", instanceID, e);
        }
    }

}
